﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using System.Xml.Linq;
using TestsModel.Enums;
using TestsModel.Parsers;
using TestUp.Models;
using TestUp.Models.AdminModels;
using TestUp.Models.Helpers;
using TestUp.Models.ShortEntities;

namespace TestUp.Controllers
{
    public class AdminController : Controller
    {
        public ActionResult ViewCourses()
        {
            UserInfo currentUser = DataHelpers.UserInfoHelper.GetUserInfo(User.Identity.Name);
            if (currentUser != null)
            {
                var model = new ViewCoursesModel
                {
                    UserName = currentUser.UserName,
                    Permission = currentUser.Permission,
                    Courses = currentUser.Courses.ToList()
                };
                return View(model);
            }
            return RedirectToAction("Index", "Home");
        }

        public ActionResult ViewGroups()
        {
            UserInfo currentUser = DataHelpers.UserInfoHelper.GetUserInfo(User.Identity.Name);
            if (currentUser != null)
            {
                var model = new ViewGroupsModel
                    {
                        UserName = currentUser.UserName,
                        Permission = currentUser.Permission,
                        Groups = DataHelpers.GroupHelper.GetAllGroups()
                    };
                return View(model);
            }
            return RedirectToAction("Index", "Home");
        }

        //viewing users of some group
        public ActionResult ViewUsers(int? id)
        {
            UserInfo currentUser = DataHelpers.UserInfoHelper.GetUserInfo(User.Identity.Name);
            Group group = null;

            if (id.HasValue)
                group = DataHelpers.GroupHelper.GetGroup(id.Value);

            if (currentUser != null)
            {
                var userInfoes = group != null
                                     ? group.UserInfoes.ToList()
                                     : DataHelpers.UserInfoHelper.GetAllUserInfoes();
                var shortUserInfoes = new List<ShortUserInfo>();
                userInfoes.ForEach(u=>shortUserInfoes.Add(u.ConvertToShortEntity()));

                var model = new ViewUsersModel
                {
                    UserName = currentUser.UserName,
                    Permission = currentUser.Permission,
                    Users = userInfoes,
                    Groups = DataHelpers.GroupHelper.GetAllGroups(),
                    Permissions = DataHelpers.PermissionHelper.GetAllPermissions()
                };
                return View(model);
            }
            return RedirectToAction("Index", "Home");
        }

        //viewing tests of some course
        public ActionResult ViewTests(int? id)
        {
            UserInfo currentUser = DataHelpers.UserInfoHelper.GetUserInfo(User.Identity.Name);
            if (currentUser != null)
            {
                var tests = new List<Test>();

                if (id.HasValue)
                {
                    var course = DataHelpers.CourseHelper.GetCourse(id.Value);
                    if (course != null)
                        tests.AddRange(course.Tests);
                }
                else
                    currentUser.Courses.ToList().ForEach(x => tests.AddRange(x.Tests));

                var model = new ViewTestsModel
                {
                    UserName = currentUser.UserName,
                    Permission = currentUser.Permission,
                    Tests = tests,
                    Courses = currentUser.Courses.ToList()
                };
                return View(model);
            }
            return RedirectToAction("Index", "Home");
        }

        public ActionResult ViewPendingTests()
        {
            UserInfo currentUser = DataHelpers.UserInfoHelper.GetUserInfo(User.Identity.Name);
            if (currentUser != null)
            {
                var pendingTests = new List<PendingTest>();
                foreach (var course in currentUser.Courses.ToList())
                {
                    foreach (var test in course.Tests.ToList())
                    {
                        pendingTests.AddRange(test.PendingTests);
                    }
                }

                var tests = new List<Test>();
                currentUser.Courses.ToList().ForEach(x=>tests.AddRange(x.Tests));

                var model = new ViewPendingTestsModel
                    {
                        UserName = currentUser.UserName,
                        Permission = currentUser.Permission,
                        PendingTests = pendingTests,
                        Groups = DataHelpers.GroupHelper.GetAllGroups(),
                        Tests = tests
                    };
                return View(model);
            }
            return RedirectToAction("Index", "Home");
        }

        #region TestsManaging
        [HttpPost]
        public ActionResult DeleteTest()
        {
            int testId;
            if (Int32.TryParse(Request["TestId"], out testId))
            {
                DataHelpers.TestHelper.DeleteTest(testId);
            }
            return RedirectToAction("ViewTests");
        }

        public ActionResult CreateTest()
        {
            var currentUser = DataHelpers.UserInfoHelper.GetUserInfo(User.Identity.Name);
            if (currentUser != null)
            {
                var shortCourses = new List<ShortCourse>();
                currentUser.Courses.ToList().ForEach(x=>shortCourses.Add(x.ConvertToShortEntity()));
                var model = new CreateTestModel
                    {
                        UserName = currentUser.UserName,
                        Permission = currentUser.Permission,
                        Courses = shortCourses,
                    };
                return View(model);
            }

            return RedirectToAction("Index", "Home");
        }

        [HttpPost]
        public ActionResult EditTest(Test test)
        {
            DataHelpers.TestHelper.UpdateTest(test);

            return RedirectToAction("ViewTests");
        }

        [HttpPost]
        public ActionResult CreateTest(Test test, HttpPostedFileBase file)
        {
            if (file == null || file.ContentType != "text/xml")
            {
                ViewBag.Message = "Content of the file should be text/xml!";
                return View("Error");
            }

            // Validate file content
            try
            {
                XmlTestParser.ParseXmlFile(XDocument.Load(file.InputStream));
                file.InputStream.Seek(0, SeekOrigin.Begin); // set stream to it`s initial position
            }
            catch
            {
                ViewBag.Message = "File has invalid structure!";
                return View("Error");
            }

            DataHelpers.TestHelper.CreateTest(test, file.InputStream, TestFileTypes.Xml);

            return RedirectToAction("ViewTests");
        }
        #endregion

        #region CoursesManaging
        [HttpPost]
        public ActionResult DeleteCourse(Course course)
        {
            DataHelpers.CourseHelper.DeleteCourse(course.CourseId);
            return RedirectToAction("ViewCourses");
        }

        [HttpPost]
        public ActionResult EditCourse(Course course)
        {
            DataHelpers.CourseHelper.UpdateCourse(course);
            return RedirectToAction("ViewCourses");
        }

        [HttpPost]
        public ActionResult CreateCourse(Course course)
        {
            UserInfo currentUser = DataHelpers.UserInfoHelper.GetUserInfo(User.Identity.Name);
            if (currentUser != null)
            {
                DataHelpers.CourseHelper.CreateCourse(course, currentUser.UserId);
                return RedirectToAction("ViewCourses");
            }
            return RedirectToAction("Index", "Home");
        }
        #endregion

        #region GroupsManaging
        [HttpPost]
        public ActionResult DeleteGroup(Group group)
        {
            DataHelpers.GroupHelper.DeleteGroup(group.GroupId);
            return RedirectToAction("ViewGroups");
        }

        [HttpPost]
        public ActionResult EditGroup(Group group)
        {
            DataHelpers.GroupHelper.UpdateGroup(group);
            return RedirectToAction("ViewGroups");
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult CreateGroup(Group model)
        {
            string groupName = model.GroupName;
            UserInfo currentUser = DataHelpers.UserInfoHelper.GetUserInfo(User.Identity.Name);
            if (currentUser != null)
            {
                DataHelpers.GroupHelper.CreateGroup(groupName);
                return RedirectToAction("ViewGroups");
            }
            return RedirectToAction("Index", "Home");
        }
        #endregion

        #region UsersManaging
        [HttpPost]
        public ActionResult DeleteUser()
        {
            int userId;
            if (int.TryParse(Request["UserId"], out userId))
            {
                DataHelpers.UserInfoHelper.DeleteUserInfo(userId);
            }
            return RedirectToAction("ViewUsers");
        }

        [HttpPost]
        public ActionResult EditUser(UserInfo user)
        {
            DataHelpers.UserInfoHelper.UpdateUserInfo(user);
            return RedirectToAction("ViewUsers");
        }

        [HttpPost]
        public ActionResult CreateUser(UserInfo user)
        {
            UserInfo currentUser = DataHelpers.UserInfoHelper.GetUserInfo(User.Identity.Name);
            if (currentUser != null)
            {
                DataHelpers.UserInfoHelper.CreateUserInfo(user);
            }
            return RedirectToAction("ViewUsers");
        }
        #endregion

        #region PendingTestsManaging
        [HttpPost]
        public ActionResult DeletePendingTest()
        {
            int pendingTestId;
            if (int.TryParse(Request["PendingTestId"], out pendingTestId))
            {
                DataHelpers.PendingTestsHelper.DeletePendingTest(pendingTestId);
            }
            return RedirectToAction("ViewPendingTests");
        }

        [HttpPost]
        public ActionResult EditPendingTest(PendingTest pendingTest)
        {
            DataHelpers.PendingTestsHelper.UpdatePendingTest(pendingTest);
            return RedirectToAction("ViewPendingTests");
        }

        [HttpPost]
        public ActionResult CreatePendingTest(PendingTest pendingTest)
        {
            var currentUser = DataHelpers.UserInfoHelper.GetUserInfo(User.Identity.Name);
            if (currentUser != null)
            {
                DataHelpers.PendingTestsHelper.CreatePendingTest(pendingTest);
            }
            return RedirectToAction("ViewPendingTests");
        }
        #endregion
    }

    public class MyAuth : AuthorizeAttribute
    {
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            var httpCookie = httpContext.Request.Cookies.Get(FormsAuthentication.FormsCookieName);
            if (httpCookie != null)
            {
                string userName = httpCookie.Name;

                return base.AuthorizeCore(httpContext);
            }
            return false;
        }
    }
}
